//Copyright (c) Microsoft Corporation.  All rights reserved.

using System;
using System.Text;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Eas.WebCrawler.Interfaces;
using Eas.WebCrawler.PlugIns.RequestComparers;

namespace Eas.WebCrawler.Test.PlugIns {
    /// <summary>
    /// Summary description for RequestComparerTest
    /// </summary>
    [TestClass]
    public class RequestComparerTest {
        public RequestComparerTest() {
            //
            // TODO: Add constructor logic here
            //
        }

        #region Additional test attributes
        //
        // You can use the following additional attributes as you write your tests:
        //
        // Use ClassInitialize to run code before running the first test in the class
        // [ClassInitialize()]
        // public static void MyClassInitialize(TestContext testContext) { }
        //
        // Use ClassCleanup to run code after all tests in a class have run
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }
        //
        // Use TestInitialize to run code before running each test 
        // [TestInitialize()]
        // public void MyTestInitialize() { }
        //
        // Use TestCleanup to run code after each test has run
        // [TestCleanup()]
        // public void MyTestCleanup() { }
        //
        #endregion

        [TestMethod]
        /// <summary>Executes the TestAlphabeticComparer test.</summary>
        public void TestAlphabeticComparer() {
            IComparer<Request> comparer = new AlphabeticComparer();
            Check(comparer, -1, RequestHelper.rGoogle, RequestHelper.rYahoo);
            Check(comparer, 1, RequestHelper.rYahoo, RequestHelper.rMSN);
            Check(comparer, 0, RequestHelper.rGoogle, new Request("http://www.google.com"));
            Check(comparer, -1, RequestHelper.rGoogle, RequestHelper.rPartial);
        }

        [TestMethod]
        /// <summary>Executes the TestAlwaysEqualComparer test.</summary>
        public void TestAlwaysEqualComparer() {
            IComparer<Request> comparer = new AlwaysEqualComparer();
            Check(comparer, 0, RequestHelper.rMSN, RequestHelper.rPartial);
            Check(comparer, 0, RequestHelper.rGoogle, new Request("http://www.google.com"));
        }

        [TestMethod]
        /// <summary>Executes the TargetDepthComparer test.</summary>
        public void TargetDepthComparer() {
            Assert.AreEqual<int>(0, RequestHelper.rGoogle.Depth);
            Assert.AreEqual<int>(1, RequestHelper.rPartial.Depth);
            Assert.AreEqual<int>(2, RequestHelper.r2Deep.Depth);
            Assert.AreEqual<int>(3, RequestHelper.r3Deep.Depth);
            Assert.AreEqual<int>(4, RequestHelper.r4Deep.Depth);

            AlwaysEqualComparer innerComparer = new AlwaysEqualComparer();
            TargetDepthComparer comparer = new TargetDepthComparer(2, innerComparer);
            Assert.AreEqual<int>(2, comparer.Depth);
            Assert.AreSame(innerComparer, comparer.InnerComparer);

            Check(comparer, 1, RequestHelper.rGoogle, RequestHelper.r2Deep);
            Check(comparer, -1, RequestHelper.rPartial, RequestHelper.r4Deep);
            Check(comparer, 0, RequestHelper.rGoogle, RequestHelper.r4Deep);
            Check(comparer, 0, new Request("http://wwww.microsoft.com", RequestHelper.rPartial), RequestHelper.r2Deep);
        }

        [TestMethod]
        /// <summary>Executes the TestSpecificHostComparer test.</summary>
        public void TestSpecificHostComparer() {
            AlwaysEqualComparer innerComparer = new AlwaysEqualComparer();
            SpecificHostComparer yesGoogleComparer = new SpecificHostComparer("www.google.com", true, innerComparer);
            SpecificHostComparer noGoogleComparer = new SpecificHostComparer("www.google.com", false, innerComparer);
            Assert.AreEqual<string>("www.google.com", yesGoogleComparer.HostName);
            Assert.IsFalse(noGoogleComparer.PreferToStayOnHost);
            Assert.AreSame(innerComparer, yesGoogleComparer.InnerComparer);

            Check(yesGoogleComparer, -1, RequestHelper.rGoogle, RequestHelper.rYahoo);
            Check(noGoogleComparer, 1, RequestHelper.rGoogle, RequestHelper.rYahoo);
            Check(yesGoogleComparer, 1, RequestHelper.rMSN, RequestHelper.rPartial);
            Check(noGoogleComparer, -1, RequestHelper.rMSN, RequestHelper.rPartial);
            Check(yesGoogleComparer, 0, RequestHelper.rPartial, RequestHelper.rGoogle);
            Check(noGoogleComparer, 0, RequestHelper.rPartial, RequestHelper.rGoogle);
        }

        [TestMethod]
        /// <summary>Executes the TestStayOnHostComparer test.</summary>
        public void TestStayOnHostComparer() {
            AlwaysEqualComparer innerComparer = new AlwaysEqualComparer();
            StayOnHostComparer stayComparer = new StayOnHostComparer(true, innerComparer);
            StayOnHostComparer leaveComparer = new StayOnHostComparer(false, innerComparer);

            Assert.AreEqual<bool>(false, leaveComparer.StayOnHost);
            Assert.AreSame(innerComparer, stayComparer.InnerComparer);

            Request stayRequest = RequestHelper.rPartial;
            Request leaveRequest = RequestHelper.r4Deep;
            Request rootRequest = RequestHelper.rGoogle;

            Check(stayComparer, -1, rootRequest, leaveRequest);
            Check(leaveComparer, 0, rootRequest, leaveRequest);

            Check(stayComparer, 0, rootRequest, stayRequest);
            Check(leaveComparer, -1, rootRequest, stayRequest);

            Check(stayComparer, 1, leaveRequest, rootRequest);
            Check(leaveComparer, 1, stayRequest, rootRequest);

            Check(stayComparer, 1, leaveRequest, stayRequest);
            Check(leaveComparer, -1, leaveRequest, stayRequest);

            Check(stayComparer, -1, stayRequest, leaveRequest);
            Check(leaveComparer, 1, stayRequest, leaveRequest);

        }

        [TestMethod]
        /// <summary>Executes the TestHashCodeComparer test.</summary>
        public void TestHashCodeComparer() {
            HashCodeComparer comparer = new HashCodeComparer();
            for (int i = 0; i < RequestHelper.AllRequests.Length - 1; i++) {
                Request left = RequestHelper.AllRequests[i];
                Request right = RequestHelper.AllRequests[i + 1];
                int iLeft = left.GetHashCode();
                int iRight = right.GetHashCode();
                Assert.AreEqual<int>(iLeft.CompareTo(iRight), comparer.Compare(left, right));
                Assert.AreEqual<int>(0, comparer.Compare(left, new Request(left.Uri)));
            }
        }



        private void Check(IComparer<Request> comparer, int result, Request left, Request right) {
            Assert.AreEqual<int>(result, comparer.Compare(left, right));
        }

    }
}
